﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpLogging;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mime;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace LogExtensions
{
    public class HttpLoggingInterceptor : IHttpLoggingInterceptor
    {
        private readonly LogConfig _logConfig;
        public HttpLoggingInterceptor(IOptionsMonitor<LogConfig> logConfig)
        {
            _logConfig = logConfig.CurrentValue;
        }
        public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
        {



            if (!MediaTypeHeaderValue.TryParse(logContext.HttpContext.Request.ContentType, out var mediaType))
            {
                 
                Console.WriteLine(mediaType?.Encoding);
            }

            //if (logContext.HttpContext.Request.Method == "POST")
            //{
            //    logContext.LoggingFields = HttpLoggingFields.None;
            //}


            //if (!logContext.IsAnyEnabled(HttpLoggingFields.Request))
            //{
            //    return default;
            //}

            //if (logContext.TryDisable(HttpLoggingFields.RequestPath))
            //{
            //    RedactPath(logContext);
            //}

            //if (logContext.TryDisable(HttpLoggingFields.RequestHeaders))
            //{
            //    RedactRequestHeaders(logContext);
            //}
            logContext.AddParameter("IpAddress", logContext.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "");
            logContext.AddParameter("name", "http");

            logContext.AddParameter("QueryString", logContext.HttpContext.Request.QueryString.ToString());
            logContext.AddParameter("Token", logContext.HttpContext.Request.Headers["Authorization"].ToString());


            if (logContext.HttpContext.Request.Path != null
            && ((_logConfig.Includes != null && !_logConfig.Includes.Any(x => logContext.HttpContext.Request.Path.ToString().ToLower().Contains(x.ToLower())))
            || (_logConfig.Excludes != null && _logConfig.Excludes.Any(x => logContext.HttpContext.Request.Path.ToString().ToLower().Contains(x.ToLower())))

            ))
            {

                logContext.TryDisable(HttpLoggingFields.All);
                logContext.LoggingFields = HttpLoggingFields.None;
                logContext.Parameters.Clear();

                return default;
            }

            return default;
        }

        public ValueTask OnResponseAsync(HttpLoggingInterceptorContext logContext)
        {
            // logContext.AddParameter("http", "httplog");
            // Don't enrich if we're not going to log any part of the response
            logContext.AddParameter("UserId", logContext.HttpContext.User.FindFirst("dn")?.Value ??logContext.HttpContext.User.FindFirst("un")?.Value);
            

            if (logContext.HttpContext.Response.ContentType != null
            && ((_logConfig.Includes != null && !_logConfig.Includes.Any(x => logContext.HttpContext.Request.Path.ToString().ToLower().Contains(x.ToLower())))
            || (_logConfig.Excludes != null && _logConfig.Excludes.Any(x => logContext.HttpContext.Request.Path.ToString().ToLower().Contains(x.ToLower())))
                ))
            {
                logContext.TryDisable(HttpLoggingFields.All);
                logContext.LoggingFields = HttpLoggingFields.None;
                logContext.Parameters.Clear();

                return default;
            }
            var statusCode = logContext.HttpContext.Response.StatusCode;

            if (logContext.HttpContext.Items.TryGetValue("code", out object? code))
            {
                if (code != null && code is int cd)
                {
                    statusCode = cd;


                }
            }
            logContext.AddParameter("code", statusCode);
            //if (!logContext.Parameters.Any(x => x.Key == "StatusCode")) {
            //    logContext.AddParameter("StatusCode", statusCode);
            //}
           // var desc = logContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata<ControllerActionDescriptor>();
           // logContext.AddParameter("code", desc.);


            if (_logConfig.StatusCodes != null
                && !_logConfig.StatusCodes.Any(x => x.Min <= statusCode && x.Max >= statusCode))
            {
                logContext.TryDisable(HttpLoggingFields.All);
                logContext.LoggingFields = HttpLoggingFields.None;
                logContext.Parameters.Clear();
                return default;
            }

            //EnrichResponse(logContext);

            return default;
        }
    }
}
